require 'digest/sha1'

class User < ActiveRecord::Base
  PermissionLevels = ['admin', 'supervisor', 'staff', 'client', 'courier'].freeze
  
  has_many :check_ins

  has_many :comments

  has_one :courier
  
  belongs_to :location
  validates_presence_of :location, :if => :validate_location?
  
  def validate_location?
    permission_level != (:courier).to_s
  end
  
  has_many :items, :foreign_key => "client_id"
  
  validates_uniqueness_of :account_name

  attr_accessor :password_confirmation
  validates_confirmation_of :password
  
  validates_inclusion_of :permission_level, :in => PermissionLevels
  
  validates_presence_of :real_name
  validates_presence_of :account_name
  
  validate :password_set
  
  # virtual attribute
  def password
    @password
  end
  
  # backed by random salt and hash
  def password=(pass)
    @password = pass
    return if pass.blank?
    create_new_salt
    self.password_hash = User.encrypted_password(self.password, self.password_salt)
  end
  
  # return the User object with account_name name if password is correct
  # return nil if the password is wrong or no User has that account_name
  def self.authenticate(name, password)
    user = self.find_by_account_name(name)
    if user
      expected_password = encrypted_password(password, user.password_salt)
      if user.password_hash != expected_password
        user = nil
      end
    end
    user
  end
  
  def self.couriers
    Courier.all.map { |x| x.user }
  end
  
  # Returns true if this user can edit the specified user
  def can_edit?(user)
    self == user ||
    permission_level == 'admin' ||
    (permission_level == 'supervisor' && location == user.location)
  end
  
  
private

  # password can't be blank
  def password_set
    errors.add(:password, "Missing password") if password_hash.blank?
  end
  
  # digest password + salt
  def self.encrypted_password(password, salt)
    string_to_hash = password + "lnk" + salt
    Digest::SHA1.hexdigest(string_to_hash)
  end
  
  # random salt
  def create_new_salt
    self.password_salt = self.object_id.to_s + rand.to_s
  end
end
